package com.cqupt.scanning.security.config;

import com.cqupt.scanning.security.filter.LoginFilter;
import com.cqupt.scanning.security.filter.TokenAuthenticationFilter;
import com.cqupt.scanning.security.utils.JwtTokenUtil;
import com.cqupt.scanning.system.acl.service.AclUserService;
import com.cqupt.scanning.system.acl.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @Description:
 * @ClassName: WebSecurityConfig
 * @Date: 2021/1/5 22:41
 * @Author: 宋宝梁
 */

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private UserDetailsServiceImpl userDetailsService;
    private JwtTokenUtil jwtTokenUtil;
    private RedisTemplate<String, Object> redisTemplate;
    private JwtSecurityProperties jwtSecurityProperties;
    private AclUserService aclUserService;

    @Autowired
    public  WebSecurityConfig(UserDetailsServiceImpl userDetailsService,
                              JwtTokenUtil jwtTokenUtil,
                              RedisTemplate<String, Object> redisTemplate,
                              JwtSecurityProperties jwtSecurityProperties,
                              AclUserService aclUserService) {
        this.userDetailsService = userDetailsService;
        this.jwtTokenUtil = jwtTokenUtil;
        this.redisTemplate = redisTemplate;
        this.jwtSecurityProperties = jwtSecurityProperties;
        this.aclUserService = aclUserService;
    }

    /**
     * 密码处理
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 加入自定义的安全认证
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

    // 配置某些接口不走过滤链(不拦截)
    @Override
    public void configure(WebSecurity web) throws Exception {
        // 添加静态资源，不走过滤链
        web.ignoring().antMatchers("/webjars/**","/doc.html",
                "/v2/**","/swagger-ui.html","/swagger-resources/**","/scanning/uploadFile/communication/**");
//        web.ignoring().antMatchers("/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling()
                .authenticationEntryPoint(new UnauthorizedEntryPoint())
                .and()
                .cors().and().csrf().disable()
                .authorizeRequests()
//                .antMatchers("/scanning/uploadFile/uploadFootFile",
//                        "/scanning/downloadFile/downloadFootPdf",
//                        "/scanning/uploadFile/uploadThreeFile",
//                        "/scanning/downloadFile/downloadThreePdf").permitAll()
                .anyRequest()
//                .permitAll()
                .authenticated()
                .and()
                .logout()
                .logoutUrl("/scanning/security/logout")
                .addLogoutHandler(new TokenLogoutHandler(jwtTokenUtil, redisTemplate, jwtSecurityProperties))
                .and()
                .addFilter(new LoginFilter(authenticationManager(), jwtTokenUtil, redisTemplate, aclUserService))
                .addFilter(new TokenAuthenticationFilter(authenticationManager(), jwtTokenUtil, redisTemplate, jwtSecurityProperties))
                .httpBasic();
    }
}
